const path = require('path')
const MiniCssPlugin = require('mini-css-extract-plugin')
const UglifyJsPlugin = require("uglifyjs-webpack-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CleanWebpackPlugin = require('clean-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const internalIp = require('internal-ip')
const webpack = require('webpack')
const config = require('./build/webpack-config')
const dev = Boolean(process.env.WEBPACK_SERVE)
const rules = config.rules({
    dev
})

function resolve (dir) {
  return path.join(__dirname, '.', dir)
}

/**
 * ==================
 * PLUGINS
 * ==================
 */
const seen = new Set();
const nameLength = 4;
const plugins = [
    // 解决vender后面的hash每次都改变
    new webpack.HashedModuleIdsPlugin(),
    new webpack.NamedChunksPlugin(chunk => {
        if (chunk.name) {
          return chunk.name;
        }
        const modules = Array.from(chunk.modulesIterable);
        if (modules.length > 1) {
          const hash = require("hash-sum");
          const joinedHash = hash(modules.map(m => m.id).join("_"));
          let len = nameLength;
          while (seen.has(joinedHash.substr(0, len))) len++;
          seen.add(joinedHash.substr(0, len));
          return `chunk-${joinedHash.substr(0, len)}`;
        } else {
          return modules[0].id;
        }
      }),
    // 处理vue文件
    new VueLoaderPlugin(),
    // 抽取css
    new MiniCssPlugin({
        filename: dev ? '[name].css' : 'css/[name].[contenthash:8].css',
        chunkFilename: dev ? '[name].css' : 'css/[name].[contenthash:8].css'
    }),
    // 使用htmlwebpackplugin插件进行html模板注入
    new HtmlWebpackPlugin({
        filename: 'index.html',
        template: 'index.html',
        inject: true,
        minify:{ //压缩HTML文件
            removeComments:true,    //移除HTML中的注释
            collapseWhitespace:true    //删除空白符与换行符
        }
    })
]

/**
 * ==================
 * MAIN CONFIG
 * ==================
 */
// const assets = path.resolve(__dirname, './')
const assets = resolve('./')
let clientConfig = {
    mode: dev ? 'development' : 'production',
    context: assets,
    entry: {
        main: './src/main.js'
    },
    output: {
        path: path.join(assets, 'dist'),
        filename: dev ? '[name].js' : 'js/[name].[chunkhash:8].js'
    },
    module: {
        rules: [
            rules.babel,
            rules.css,
            rules.scss,
            rules.vue
        ]
    },
    resolve: {
        extensions: ['*', '.js', '.json', '.vue', '.tsx', '.ts'],
        alias: {
            'vue$': 'vue/dist/vue.esm.js',
            '@': resolve('src'),
            'common': resolve('common')
            // static: path.resolve(assets, '../static/')
        }
    },
    plugins: plugins,
    devtool: dev ? 'source-map' : false,
    performance: {
        hints: false
    },
    // 是否在控制台显示统计信息
    stats: 'normal'
}

/**
 * ==================
 * 开发环境和生产环境配置区分
 * ==================
 */
if (dev) {
    clientConfig.cache = true
    // 此选项配合webpack-serve插件使用
    clientConfig.serve = {
        host: '0.0.0.0',
        hot: {
            host: {
                client: internalIp.v4.sync(),
                server: '0.0.0.0'
            }
        },
        port: config.port
    }
} else {

    clientConfig.plugins.unshift(
        // 构建的时候先清空dist目录
        new CleanWebpackPlugin('./dist/*', {
            root: __dirname,
            // 是否显示在控制台
            verbose: true,
            // 是否模拟删除
            dry: false
        }))

    clientConfig.optimization = {
        minimizer: [
            // js压缩
            new UglifyJsPlugin({
                uglifyOptions: {
                    compress: {
                        // warnings: false,       // 去除警告
                        drop_debugger: true,   // 去除debugger
                        // drop_console: true,  // 删除所有的“console”语句
                        // 如果需要去除console.log 保留 console.error或者console.info的话，使用下面这个配置，如果需要去除所有的console函数,则使用上面的drop_console属性
                        pure_funcs: ['console.log']
                    }
                },
                cache: true,     // 开启缓存
                parallel: true,  // 平行压缩
                sourceMap: false // set to true if you want JS source maps
            }),
            // css压缩
            new OptimizeCSSAssetsPlugin({})
        ],
        splitChunks: config.splitChunks()
    }
}

module.exports = clientConfig